package com.tencent.sr.iris.activity.common.util;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;

/**
 * @author nixiaolin
 * @date 2022/12/9 13:00
 */
@Slf4j
public abstract class ConcurrentUtils {

    /**
     * 所有结果处理成功
     *
     * @param futures
     * @param handler
     * @param <T>
     * @return
     */
    public static <T> boolean allOf(Function<T, Boolean> handler, CompletableFuture<T>... futures) {

        try {
            return CompletableFuture.allOf(futures).thenApply(i -> {
                for (CompletableFuture<T> future : futures) {
                    try {
                        if (!handler.apply(future.get())) {
                            return Boolean.FALSE;
                        }
                    } catch (Exception e) {
                        log.error("多线程运行错误：", e);
                        return Boolean.FALSE;
                    }
                }
                return Boolean.TRUE;
            }).get();
        } catch (Exception e) {
            log.error("多线程运行错误：", e);
        }
        return Boolean.FALSE;
    }

    /**
     * 所有结果处理成功
     *
     * @param futures
     * @param handler
     * @param <T>
     * @return
     */
    public static <T> boolean allOf(Function<T, Boolean> handler, List<CompletableFuture<T>> futures) {
        return allOf(handler, futures.toArray(new CompletableFuture[futures.size()]));
    }

    /**
     * 所有结果处理成功
     *
     * @param futures
     * @param <E>
     * @return
     */
    public static <E> List<E> allOf(List<CompletableFuture<List<E>>> futures) throws Exception {
        return CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).thenApply(i -> {
            List<E> res = Lists.newArrayList();
            for (CompletableFuture<List<E>> future : futures) {
                try {
                    List<E> r = future.get();
                    res.addAll(r);
                } catch (Exception e) {
                    log.error("获取多线程运行结果错误：", e);
                }
            }
            return res;
        }).get();
    }

}
